//
// Created by hamlet on 2022/1/14.
//

#include "room.h"
#include <QApplication>
#include <QRandomGenerator64>

RoomInfo::RoomInfo(QUrl url, QString name, RoomInfo::SizeType sizeType, RoomInfo::RoomType roomType, int playerNum,
                   int gameNum, int time, int life, RoomInfo::FruitType fruitType, int fruitAmount, QSize size,
                   qint64 id)
        : Message(Message::Type::RoomInfo), m_url(qMove(url)), m_name(qMove(name)), m_sizeType(sizeType),
          m_roomType(roomType), m_playerNum(playerNum), m_gameNum(gameNum), m_time(time), m_life(life),
          m_fruitType(fruitType), m_fruitAmount(fruitAmount), m_size(m_sizeType == SizeType::Custom ? size : QSize{}),
          m_ID(id) {
//    while (!m_ID)
//        m_ID = static_cast<qint64>(QRandomGenerator64::global()->generate64());
    if (m_name.isEmpty())
        m_name = QApplication::tr("未命名");
}

RoomInfo *RoomInfo::parseJson(const QJsonObject &json) {
    return new RoomInfo{QUrl{json["url"].toString()}, json["name"].toString(),
                        static_cast<SizeType>(json["sizeType"].toInt()),
                        static_cast<RoomType>(json["roomType"].toInt()), json["playerNum"].toInt(),
                        json["gameNum"].toInt(), json["time"].toInt(), json["life"].toInt(),
                        static_cast<FruitType>(json["fruitType"].toInt()), json["fruitAmount"].toInt(),
                        QSize(json["size_w"].toInt(), json["size_h"].toInt()), json["id"].toInteger()};
}

QJsonObject RoomInfo::toJson() const {
    return {{"type",        static_cast<int>(Message::Type::RoomInfo)},
            {"id",          m_ID},
            {"url",         m_url.toString()},
            {"name",        m_name},
            {"sizeType",    static_cast<int>(m_sizeType)},
            {"roomType",    static_cast<int>(m_roomType)},
            {"playerNum",   m_playerNum},
            {"gameNum",     m_gameNum},
            {"time",        m_time},
            {"life",        m_life},
            {"fruitType",   static_cast<int>(m_fruitType)},
            {"fruitAmount", m_fruitAmount},
            {"size_w",      m_size.width()},
            {"size_h",      m_size.height()}};
}

inline QString hexDisplay(qint64 num) {
    QString output;
    auto p = (char8_t *) &num;
    for (int i = 0; i < 8; ++i) {
        char8_t digit = p[i] >> 4;
        output.append(QChar((digit < 10 ? '0' : '7') + digit));
        digit = p[i] - (digit << 4);
        output.append(QChar((digit < 10 ? '0' : '7') + digit));
    }
    return qMove(output);
}

QString RoomInfo::simpleInfo() {
    return qMove(QString("%1 %2 %3").arg(hexDisplay(m_ID), m_name, m_url.toString()));
}

QString RoomInfo::fullInfo() {
    QSize size = m_size;
    switch (m_sizeType) {
        case SizeType::Big:
            m_size = SIZE_BIG;
            break;
        case SizeType::Medium:
            m_size = SIZE_MEDIUM;
            break;
        case SizeType::Small:
            m_size = SIZE_SMALL;
            break;
        case SizeType::Custom:
            break;
    }
    return qMove(QApplication::tr("<html><head/><body>"
                                  "<p>名称：%1</p><p>地图大小：%2×%3</p><p>地图种类：%4</p><p>人数：%5</p><p>局数：%6</p><p>游戏时间：%7秒</p>"
                                  "<p>初始生命值：%8</p><p>果实种类：%9</p><p>果实数量：%10</p></body></html>")
                         .arg(m_name).arg(m_size.width()).arg(m_size.height()).arg("不知道").arg(m_playerNum)
                         .arg(m_gameNum).arg(m_time).arg(m_life).arg("太多了").arg(m_fruitAmount));
}
